/* SPDX-License-Identifier: Apache-2.0 */

/* global expect, describe, it */

import {gettext, ngettext, ngettextCustom} from "../../warehouse/static/js/warehouse/utils/messages-access";


describe("messages access util", () => {

  describe("gettext with defaults", () => {
    it.each([
      // uses default singular when no translation is available
      {
        singular: "My default message.",
        extras: [],
        expected: "My default message.",
      },
      // inserts placeholders into the default singular
      {
        singular: "My default message: %1",
        extras: ["more message here"],
        expected: "My default message: more message here",
      },
    ])("translates $singular $extras to '$expected'", async (
      {singular, extras, expected},
    ) => {
      const result = gettext(singular, ...extras);
      expect(result).toEqual(expected);
    });
  });

  describe("ngettext with defaults", () => {
    it.each([
      // uses default singular when no translation is available
      {
        singular: "My default message.",
        plural: "My default messages.",
        num: 1,
        extras: [],
        expected: "My default message.",
      },
      // inserts placeholders into the default singular
      {
        singular: "My %2 default %1 message.",
        plural: "My default messages.",
        num: 1,
        extras: ["more message here", "something else"],
        expected: "My something else default more message here message.",
      },
      // uses default plural when no translation is available
      {
        singular: "My default message.",
        plural: "My default messages.",
        num: 2,
        extras: [],
        expected: "My default messages.",
      },
      // inserts placeholders into the default plural
      {
        singular: "My %2 default %1 message.",
        plural: "My default plural messages %1 %2.",
        num: 2,
        extras: ["more message here", "something else"],
        expected: "My default plural messages more message here something else.",
      },
    ])("translates $singular $plural $num $extras to '$expected'", async (
      {singular, plural, num, extras, expected},
    ) => {
      const result = ngettext(singular, plural, num, ...extras);
      expect(result).toEqual(expected);
    });
  });

  describe("with data 'en' having more than one plural form", () => {
    // This is the locale data, as would be embedded into
    // messages-access.js by webpack.plugin.localize.js.
    const data = {
      "": {"language": "en", "plural-forms": "nplurals = 2; plural = (n != 1);"},
      "My default message.": "My translated message.",
      "My %2 message with placeholders %1.": "My translated %1 message with placeholders %2",
      "My message with plurals": ["My translated message 1.", "My translated messages 2."],
      "My message with plurals %1 again": ["My translated message 1 %1.", "My translated message 2 %1."],
    };
    // This is the plural form function, as would be embedded into
    // messages-access.js by webpack.plugin.localize.js.
    // The eslint rules are disabled here because the pluralForms function is
    // generated by webpack.plugin.localize.js and this test must match a generated function.
    /* eslint-disable */
    const pluralForms = function (n) {
      let nplurals, plural;
      nplurals = 2; plural = (n != 1);
      return {total: nplurals, index: ((nplurals > 1 && plural === true) ? 1 : (plural ? plural : 0))};
    };
    /* eslint-enable */
    it.each([
      // has invalid singular empty
      {
        singular: "",
        plural: null,
        num: 1,
        extras: [],
        expected: "",
      },
      // has invalid singular whitespace only
      {
        singular: "    ",
        plural: null,
        num: 1,
        extras: [],
        expected: "",
      },
      // uses singular when translation is available
      {
        singular: "My default message.",
        plural: null,
        num: 1,
        extras: [],
        expected: "My translated message.",
      },
      // inserts placeholders into the singular translation
      {
        singular: "My %2 message with placeholders %1.",
        plural: null,
        num: 1,
        extras: ["str A", "strB"],
        expected: "My translated str A message with placeholders strB",
      },
      // uses plural when translation is available
      {
        singular: "My message with plurals",
        plural: "My messages with plurals",
        num: 2, extras: ["not used"],
        expected: "My translated messages 2.",
      },
      // inserts placeholders into the plural translation
      {
        singular: "My message with plurals %1 again",
        plural: "My messages with plurals %1 again",
        num: 2,
        extras: ["waves"],
        expected: "My translated message 2 waves.",
      },
    ])("translates $singular $plural $num $extras to '$expected'", async (
      {singular, plural, num, extras, expected},
    ) => {
      const result = ngettextCustom(singular, plural, num, extras, data, pluralForms);
      expect(result).toEqual(expected);
    });
  });

  describe("with custom data having only one plural form", () => {
    // This is the locale data, as would be embedded into
    // messages-access.js by webpack.plugin.localize.js.
    const data = {
      "": {"language": "id", "plural-forms": "nplurals = 1; plural = 0;"},
      "My default message.": "My translated message.",
      "My %2 message with placeholders %1.": "My translated %1 message with placeholders %2",
      "My message with plurals": ["My translated message 1.", "My translated messages 2."],
      "My message with plurals %1 again": ["My translated message 1 %1.", "My translated message 2 %1"],
    };
    // This is the plural form function, as would be embedded into
    // messages-access.js by webpack.plugin.localize.js.
    // The eslint rules are disabled here because the pluralForms function is
    // generated by webpack.plugin.localize.js and this test must match a generated function.
    /* eslint-disable */
    const pluralForms = function (n) { // eslint-disable-line no-unused-vars
      let nplurals, plural;
      nplurals = 1; plural = 0;
      return {total: nplurals, index: ((nplurals > 1 && plural === true) ? 1 : (plural ? plural : 0))};
    };
    /* eslint-enable */
    it.each([
      // has invalid singular empty
      {
        singular: "",
        plural: null,
        num: 1,
        extras: [],
        expected: "",
      },
      // has invalid singular whitespace only
      {
        singular: "    ",
        plural: null,
        num: 1,
        extras: [],
        expected: "",
      },
      // uses singular when translation is available
      {
        singular: "My default message.",
        plural: null,
        num: 1,
        extras: [],
        expected: "My translated message.",
      },
      // inserts placeholders into the singular translation
      {
        singular: "My %2 message with placeholders %1.",
        plural: null,
        num: 1,
        extras: ["str A", "strB"],
        expected: "My translated str A message with placeholders strB",
      },
      // uses first plural when translation is available
      {
        singular: "My message with plurals",
        plural: "My messages with plurals",
        num: 2, extras: ["not used"],
        expected: "My translated message 1.",
      },
      // inserts placeholders into the first plural translation
      {
        singular: "My message with plurals %1 again",
        plural: "My messages with plurals %1 again",
        num: 2,
        extras: ["waves"],
        expected: "My translated message 1 waves.",
      },
    ])("translates $singular $plural $num $extras to '$expected'", async (
      {singular, plural, num, extras, expected},
    ) => {
      const result = ngettextCustom(singular, plural, num, extras, data, pluralForms);
      expect(result).toEqual(expected);
    });
  });
});
